﻿using System.Collections.Generic;
using System.IO;

namespace JQueryControlToolkit
{

    /// <summary>
    /// An server representation of an atomic operation on the DOM.
    /// </summary>
    public class DomOperation
    {
        public string OperationType { get; set; }
        public Dictionary<string, object> Parameters { get; set; }
        public string Code { get; set; }

        #region Static Helpers

        public static void ToScript<T>(TextWriter toScript, IEnumerable<KeyValuePair<string, T>> jsObject)
        {
            toScript.Write("{");
            bool isFirst = true;
            foreach (KeyValuePair<string, T> parameter in jsObject)
            {
                if (!isFirst)
                    toScript.Write(", ");
                else
                    isFirst = false;

                if (parameter.Key != string.Empty)
                {
                    ToScript(toScript, parameter.Key);
                    toScript.Write(":");
                }
                ToScript(toScript, parameter.Value);
            }
            toScript.Write("}");
        }

        public static void ToScript(TextWriter toScript, string stringToEscape)
        {
            toScript.Write(DomResult.Escape(stringToEscape));
        }

        public static void ToScript(TextWriter toScript, System.Collections.IEnumerable collection, bool addBrackets)
        {
            if (collection is IEnumerable<KeyValuePair<string, object>>)
            {
                ToScript<object>(toScript, (IEnumerable<KeyValuePair<string, object>>)collection);
                return;
            }

            if (addBrackets)
                toScript.Write("[");
            bool isFirst = true;
            foreach (object param in collection)
            {
                if (isFirst)
                    isFirst = false;
                else
                    toScript.Write(",");
                ToScript(toScript, param);
            }
            if (addBrackets)
                toScript.Write("]");
        }

        public static void ToScript(TextWriter toScript, DomOperation operation)
        {
            operation.ToScript(toScript);
        }

        public static void ToScript(TextWriter toScript, object param, bool addBracketIfArray = true)
        {
            if (param is JQuery)
                ToScript(toScript, (JQuery)param);
            else if (param is JSObject)
                ToScript(toScript, (JSObject)param);
            else if (param is bool)
                ToScript(toScript, (bool)param);
            else if (param is string)
                ToScript(toScript, (string)param);
            else if (param is System.Collections.IEnumerable)
                ToScript(toScript, (System.Collections.IEnumerable)param, addBracketIfArray);
            else if (param is DomOperation)
                ToScript(toScript, (DomOperation)param);
            else
            {
                System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
                toScript.Write(serializer.Serialize(param));
            }
        }

        public static void ToScript(TextWriter toScript, JQuery jq)
        {
            jq.ToScript(toScript);
        }

        public static void ToScript(TextWriter toScript, JSObject obj)
        {
            ((JSObject)obj).ToScript(toScript);
        }

        public static void ToScript(TextWriter toScript, bool condition)
        {
            toScript.Write(condition ? "true" : "false");
        }

        #endregion

        internal void ToScript(TextWriter toScript)
        {
            toScript.Write(Code);
            if (Parameters != null)
            {
                if (Parameters.Count == 1 && Parameters.ContainsKey(string.Empty))
                {
                    toScript.Write("(");
                    object parameter = Parameters[string.Empty];
                    ToScript(toScript, parameter, false);
                    if (!string.IsNullOrEmpty(Code))
                        toScript.Write(")");
                }
                else
                {
                    if (!string.IsNullOrEmpty(Code))
                        toScript.Write("(");
                    ToScript(toScript, Parameters);
                    if (!string.IsNullOrEmpty(Code))
                        toScript.Write(")");
                }
            }
        }
    }
}